package com.sayimo.maker.commons.wx.pay;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import sun.misc.BASE64Encoder;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.sayimo.maker.commons.Constant;
import com.sayimo.maker.commons.utils.Base64Utils;
import com.sayimo.maker.commons.utils.JSONUtil;
import com.sayimo.maker.commons.utils.MatrixToImageWriter;
import com.sayimo.maker.commons.utils.PropertiesUtils;
import com.sayimo.uploadfile.util.UploadFileInfo;
import com.sayimo.uploadfile.util.UploadFileResult;


/**  
 * @Title: WXScanCodePay.java
 * @Description:微信扫码支付
 * @author tanxin
 * @date 2017年3月28日  下午2:59:52
 */
public class WXScanCodePay {
	
	private static Log logger = LogFactory.getLog(WXScanCodePay.class);
	
	private static String APP_ID = PropertiesUtils.getValue("WX_APPID");//微信开发平台应用id

	private static String MCH_ID= PropertiesUtils.getValue("WX_MCHID");;//商业号
	
	private static String API_KEY= PropertiesUtils.getValue("WX_PAY_API_KEY");//API_KEY
	
	private static String UFDODER_URL= "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信开发平台应用id
	
	public static Map<String,Object> weixin_pay(Map _paramMap, HttpServletRequest req) throws Exception {
		
		Map resultMap = new HashMap();
		Map params = new HashMap();
		
		try {
			
			//发起支付ip
			String CREATE_IP= req.getRemoteAddr();
			//回调地址。测试回调必须保证外网能访问到此地址
			String NOTIFY_URL= PropertiesUtils.getValue("SERVER_URL") + req.getContextPath()+"/orders/callbackalipay";
		   
			// 账号信息  
		    String appid = APP_ID;  // appid  
		    String mch_id = MCH_ID; // 商业号  
		    String key = API_KEY; // key  
		
		    String currTime = PayCommonUtil.getCurrTime();  
		    String strTime = currTime.substring(8, currTime.length());  
		    String strRandom = PayCommonUtil.buildRandom(4) + "";  
		    String nonce_str = strTime + strRandom;  
		      
		    Double totalPrice = (Double) _paramMap.get("payPrice");
			/** 总金额(分为单位) */
			int order_price = (int) (totalPrice * 100);// 价格   注意：价格的单位是分  
		    String body = (String) _paramMap.get("goodsName");   // 商品名称  
		    String out_trade_no = (String) _paramMap.get("ordersNo"); // 订单号  
		      
		    // 获取发起电脑 ip  
		    String spbill_create_ip = CREATE_IP;  
		    // 回调接口   
		    String notify_url = NOTIFY_URL;  
		    String trade_type = "NATIVE";  
		      
		    SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  
		    packageParams.put("appid", appid);  
		    packageParams.put("mch_id", mch_id);  
		    packageParams.put("nonce_str", nonce_str);  
		    packageParams.put("body", body);  
		    packageParams.put("out_trade_no", out_trade_no);  
		    packageParams.put("total_fee", order_price);  
		    packageParams.put("spbill_create_ip", spbill_create_ip);  
		    packageParams.put("notify_url", notify_url);  
		    packageParams.put("trade_type", trade_type);  
		
		    // 微信回掉参数
	        {
		        Map<String, Object> passBackMap = new HashMap<>();
		        Set<String> keys = _paramMap.keySet();
		        for (String pmkey : keys) {
					if (!pmkey.startsWith("_")) {
						continue;
					}						
					passBackMap.put(pmkey, _paramMap.get(pmkey));
				}	        
		        if (MapUtils.isNotEmpty(passBackMap)) {
		        	String passBackParams = JSONUtil.writeValueAsString(passBackMap);
			        logger.info("**********************passBackParams = " + passBackParams);
			        packageParams.put("attach",URLEncoder.encode(passBackParams, "UTF-8"));  //公用回传参数，如果请求时传递了该参数，则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝
		        }
	        }
	        
		    String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);  
		    packageParams.put("sign", sign);  
		      
		    String requestXML = PayCommonUtil.getRequestXml(packageParams);  
		    System.out.println(requestXML);  
		
		    String resXml = WXHttpUtil.postData(UFDODER_URL, requestXML);  
		
		      
		    Map map = WXXMLUtil.doXMLParse(resXml);  
		    String urlCode = (String) map.get("code_url");  
		    logger.info("&&&&&&&&&&&&&&&&&&&&&&&urlCode="+urlCode);
		    //生成二维码图片并返回url地址
		    String WXQRCodeUrl=WXQRCodeUrl(urlCode);
		    //放入二维码图片地址
		    params.put("WXQRCodeUrl", WXQRCodeUrl);
		    logger.info("params = " + JSONUtil.writeValueAsString(params));
			resultMap.put(Constant.STATUS, Constant.STATUS_SUCCESS);
			resultMap.put(Constant.DATA, params);
			logger.info("resultMap = " + JSONUtil.writeValueAsString(resultMap));
	
			return resultMap;
	
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}  
	/**
	 * @Package com.sayimo.maker.commons.wx.pay
	 * @Author 谭新
	 * @MethodName: WXQRCodeUrl
	 * @Description:生成二维码图片并返回url地址
	 * @return String
	 * @Date 2017年3月28日,下午5:45:53
	 */
	public static String WXQRCodeUrl(String urlCode) throws Exception{
		// 生成二维码
		// 设置二维码内容
		String content = urlCode;
		String path = PropertiesUtils.getValue("UPLOAD_FILE_PATH") + PropertiesUtils.getValue("FILE_SAVE_PATH")
				+ "/payqrcode";
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		Map hints = new HashMap();
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300, hints);
		File file1 = new File(path, "ACCOUNT_QR_CODE.jpg");
		MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file1);

		InputStream in = null;
		byte[] data = null;
		// 读取图片字节数组
		try {
			in = new FileInputStream(file1.getPath());
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 对字节数组Base64编码
		BASE64Encoder encoder = new BASE64Encoder();
		String fileStr = encoder.encode(data);// 返回Base64编码过的字节数组字符串
		String filePath = PropertiesUtils.getValue("FILE_SAVE_PATH") + "/payqrcode";
		String imagePath = PropertiesUtils.getValue("PAYQRIMGPATH");
		UploadFileResult uploadResult = Base64Utils.uploadByBase64(PropertiesUtils.getValue("UPLOAD_SERVER_BASE64"),
				fileStr, "支付二维码.jpg", filePath, imagePath);
		UploadFileInfo fileInfo = uploadResult.getFiles()[0];
		String matrixLink = String.valueOf(fileInfo.getFileUrl() + "/" + fileInfo.getProFileName());
		if (matrixLink != null) {
			return matrixLink;
		} else {
			return "www.baidu.com";
		}
	}
}